import datetime
import re

import jwt
from django_redis import get_redis_connection
from rest_framework import serializers, settings


from apps.users.models import User


# 注册序列化器
class CreateUserSerializer(serializers.ModelSerializer):
    sms_code = serializers.CharField(label='短信验证码', write_only=True)
    token = serializers.CharField(label='token', read_only=True)

    class Meta:
        model = User
        fields = ['id', 'username', 'password', 'mobile', 'token', 'avatar', 'sms_code']
        extra_kwargs = {
            'username': {
                'min_length': 4,
                'max_length': 20,
                'error_messages': {
                    'min_length': '用户名为4-20个字符!',
                    'max_length': '用户名为4-20个字符!',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 4,
                'max_length': 20,
                'error_messages': {
                    'min_length': '密码为4-20个字符',
                    'max_length': '密码为4-20个字符',
                }
            }
        }

    def validate_mobile(self, value):
        print(value)
        if not re.match(r'^1[345789]\d{9}$', value):
            raise serializers.ValidationError('手机格式不正确')
        return value

    def validate(self, attrs):
        # 链接redis数据库
        sms_redis_client = get_redis_connection('sms_code')
        # 取出mobile
        mobile = attrs.get('mobile')
        print(mobile)
        # 取出验证码
        mobile_redis = sms_redis_client.get("sms_%s" % mobile)
        # 取出验证码
        sms = attrs.get('sms_code')
        print(sms)
        if mobile_redis is None:
            raise serializers.ValidationError('验证码失效')
        if sms != mobile_redis.decode():
            raise serializers.ValidationError('验证码错误')
        return attrs

    def create(self, validated_data):
        del validated_data['sms_code']
        user = super().create(validated_data)
        user.set_password(validated_data['password'])
        print(user.mobile)
        user.save()
        # 3.设置载体
        payload = {
            "user_id": user.id,
            "username": user.username,
            # 设置过期时间
            'exp': datetime.utcnow() + datetime.timedelta(days=1)
        }

        # 4.加密
        token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')
        user.token = token.decode()
        return user
